<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="KOHPe" id="KOHPe"><span data-lake-id="ua7b1fb64" id="ua7b1fb64">典型回答</span></h1>
  <p data-lake-id="udbfc8ece" id="udbfc8ece"><br></p>
  <p data-lake-id="u413fbea4" id="u413fbea4"><span data-lake-id="uc41db82a" id="uc41db82a">在分布式事务的实现中，有很多种方案，其中比较常用的就是基于MQ来实现，在MQ的具体实现中，又有很多种具体的方案，从大的方面来说可以分为两种：</span></p>
  <ul list="u12b9d72a">
   <li fid="ub0ab23a7" data-lake-id="u757b03f0" id="u757b03f0"><span data-lake-id="u6af13ab6" id="u6af13ab6">可靠消息最终一致性</span></li>
   <li fid="ub0ab23a7" data-lake-id="u72c39e27" id="u72c39e27"><span data-lake-id="u2a756419" id="u2a756419">最大努力通知</span></li>
  </ul>
  <p data-lake-id="u8d052ed6" id="u8d052ed6"><span data-lake-id="uef373ae8" id="uef373ae8">​</span><br></p>
  <h3 data-lake-id="AcZYJ" id="AcZYJ"><span data-lake-id="uf649fe44" id="uf649fe44">可靠消息最终一致性</span></h3>
  <p data-lake-id="u3fce9911" id="u3fce9911"><br></p>
  <p data-lake-id="u8bdf15b7" id="u8bdf15b7"><span data-lake-id="uae4307e4" id="uae4307e4" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">可靠消息最终一致性，顾名思义就是依赖可靠的消息，来实现一种最终一致性的模型。</span></p>
  <p data-lake-id="ubfb28651" id="ubfb28651"><span data-lake-id="u0d9677be" id="u0d9677be" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">​</span><br></p>
  <p data-lake-id="u9961cb79" id="u9961cb79"><span data-lake-id="u25de164c" id="u25de164c" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">他的大致流程就是：</span></p>
  <p data-lake-id="u444aead5" id="u444aead5"><span data-lake-id="ue654c868" id="ue654c868" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">1、事务的发起方执行本地事务</span></p>
  <p data-lake-id="uafa192a4" id="uafa192a4"><span data-lake-id="u26e9a854" id="u26e9a854" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">2、事务的发起方向事务的参与方发送MQ消息</span></p>
  <p data-lake-id="u60cd6c69" id="u60cd6c69"><span data-lake-id="u11b042ea" id="u11b042ea" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">3、事务的参与方接收到MQ消息后执行自己的本地事务</span></p>
  <p data-lake-id="ud1cfea10" id="ud1cfea10"><span data-lake-id="u7bdcd0e1" id="u7bdcd0e1" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">​</span><br></p>
  <p data-lake-id="u0e3b036e" id="u0e3b036e"><span data-lake-id="u716915c4" id="u716915c4" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">这里面事务的发起方和参与方都需要各自执行本地事务，他们之间，通过可靠消息来保障最终一致。</span></p>
  <p data-lake-id="u0503cec4" id="u0503cec4"><span data-lake-id="u87bc1d2c" id="u87bc1d2c" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">​</span><br></p>
  <p data-lake-id="u66763528" id="u66763528"><span data-lake-id="uead0350f" id="uead0350f" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">那么，怎么样的消息算可靠呢，直接依赖kafka、rocketMQ发送一个消息就可靠了么？显然是不行的，因为我们知道，在出现网络分区、网络延迟等情况时，是没办法保证消息一定可以发出去的，也没办法保证消息发出去就一定能被成功消费。</span></p>
  <p data-lake-id="u81fb9577" id="u81fb9577"><span data-lake-id="uaf102724" id="uaf102724" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">​</span><br></p>
  <p data-lake-id="u1a03296c" id="u1a03296c"><span data-lake-id="u86a5b00c" id="u86a5b00c" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">那么想要做到让这个消息可靠，一般由两种做法：</span></p>
  <p data-lake-id="u08a129f3" id="u08a129f3"><span data-lake-id="u987389e9" id="u987389e9" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">​</span><br></p>
  <p data-lake-id="u4e49960e" id="u4e49960e"><span data-lake-id="u42dbea84" id="u42dbea84" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">1、本地消息表</span></p>
  <p data-lake-id="u61309b56" id="u61309b56"><span data-lake-id="u5700f03b" id="u5700f03b" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">​</span><br></p>
  <p data-lake-id="u98edbb81" id="u98edbb81"><br></p>
  <p data-lake-id="uf78d7aa0" id="uf78d7aa0"><span data-lake-id="u824382eb" id="u824382eb" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">2、事务消息</span></p>
  <p data-lake-id="u74385a40" id="u74385a40"><span data-lake-id="ud43e5e61" id="ud43e5e61" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">​</span><br></p>
  <p data-lake-id="u9693bd0a" id="u9693bd0a"><span data-lake-id="u9a4a9e45" id="u9a4a9e45" class="lake-fontsize-11" style="color: rgb(51, 51, 51)">​</span><br></p>
  <p data-lake-id="u851d6aac" id="u851d6aac"><span data-lake-id="u4485016e" id="u4485016e" class="lake-fontsize-11">通过这两种方案，都可以保证事务的发起方在执行完本地事务之后，消息一定可以发出去，并且一定能被消费成功。</span></p>
  <p data-lake-id="uccc46b4c" id="uccc46b4c"><br></p>
  <p data-lake-id="ub0e533e5" id="ub0e533e5"><span data-lake-id="ua27170f4" id="ua27170f4" class="lake-fontsize-11">本地消息表的方案是基于本地事务+重试，来保证MQ消息一定可以发出去。</span></p>
  <p data-lake-id="ue0534e45" id="ue0534e45"><span data-lake-id="ufdf32ba8" id="ufdf32ba8" class="lake-fontsize-11">事务消息的方案是基于MQ的事务消息机制，把一条消息拆成两个half消息，通过2阶段的方式+回调反查来保证消息一定能发出去。</span></p>
  <p data-lake-id="ua258adfd" id="ua258adfd"><br></p>
  <p data-lake-id="u5ea7bcc0" id="u5ea7bcc0"><span data-lake-id="uaf113e4c" id="uaf113e4c" class="lake-fontsize-11">2者都是依赖MQ自身的重试机制+事务参与者反查+对账来保证消息一定可以消费。</span></p>
  <p data-lake-id="u770d62d4" id="u770d62d4"><span data-lake-id="uef6a66a5" id="uef6a66a5" class="lake-fontsize-11">​</span><br></p>
  <p data-lake-id="u54279b34" id="u54279b34"><span data-lake-id="u0b01da94" id="u0b01da94" class="lake-fontsize-11">​</span><br></p>
  <h3 data-lake-id="KwGgk" id="KwGgk"><span data-lake-id="u0483ce8c" id="u0483ce8c">最大努力通知</span></h3>
  <p data-lake-id="uc370690b" id="uc370690b"><br></p>
  <p data-lake-id="u6ff3ec51" id="u6ff3ec51"><span data-lake-id="u40d6ce8a" id="u40d6ce8a" class="lake-fontsize-11">除了可靠消息最终一致性这种以外，还有一种方式就是也使用消息，但是这个消息并不要求一定可靠。这就是最大努力通知。</span></p>
  <p data-lake-id="uc2be19bb" id="uc2be19bb"><span data-lake-id="u552b6bd4" id="u552b6bd4" class="lake-fontsize-11">​</span><br></p>
  <p data-lake-id="u09721ab8" id="u09721ab8"><span data-lake-id="uc3621e09" id="uc3621e09" class="lake-fontsize-11">​</span><br></p>
  <p data-lake-id="uc3089207" id="uc3089207"><span data-lake-id="u256a2730" id="u256a2730" class="lake-fontsize-11">这个方案一般就是只依赖重试机制，来做最大努力的通知事务参与者。但是需要注意的是，在最大努力通知的过程中，可能会出现消息重复发送的情况，也可能会出现消息丢失的情况。</span></p>
  <p data-lake-id="u5e8e3108" id="u5e8e3108"><span data-lake-id="u327bf015" id="u327bf015" class="lake-fontsize-11">​</span><br></p>
  <h1 data-lake-id="MVI59" id="MVI59"><span data-lake-id="u0f5e1351" id="u0f5e1351">扩展知识</span></h1>
  <p data-lake-id="u9f2c9bbd" id="u9f2c9bbd"><br></p>
  <h3 data-lake-id="pWZZu" id="pWZZu"><span data-lake-id="udbe281ff" id="udbe281ff">三者区别</span></h3>
  <p data-lake-id="u4497ec37" id="u4497ec37"><br></p>
 </body>
</html>